package com.example.orderservice.consumer;

import com.example.orderservice.event.OrderCreatedEvent;
import com.example.orderservice.model.Inventory;
import com.example.orderservice.model.OrderLog;
import com.example.orderservice.repository.InventoryRepository;
import com.example.orderservice.repository.OrderLogRepository;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

@Service
public class OrderEventConsumer implements MessageListener {
    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private InventoryRepository inventoryRepository;

    @Autowired
    private OrderLogRepository orderLogRepository;

    private static final int MAX_RETRIES = 3;
    private static final long RETRY_DELAY_MS = 2000;

    @Override
    public void onMessage(Message message, byte[] pattern) {
        try {
            // 反序列化事件
            String eventJson = new String(message.getBody());
            OrderCreatedEvent event = objectMapper.readValue(eventJson, OrderCreatedEvent.class);
            System.out.println("Received event: " + event);

            // 1. 更新库存（带重试机制）
            updateInventoryWithRetry(event, MAX_RETRIES);

            // 2. 记录日志
            logOrder(event);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void updateInventoryWithRetry(OrderCreatedEvent event, int retries) throws Exception {
        int attempt = 0;
        while (attempt < retries) {
            try {
                String[] items = event.getItems().split(",\\s*");
                for (String item : items) {
                    Inventory inventory = inventoryRepository.findByItemName(item);
                    if (inventory != null && inventory.getQuantity() > 0) {
                        inventory.setQuantity(inventory.getQuantity() - 1);
                        inventoryRepository.save(inventory);
                        System.out.println("Updated inventory for " + item + ": " + inventory.getQuantity());
                    } else {
                        throw new RuntimeException("Inventory update failed for item: " + item);
                    }
                }
                return; // 成功更新，退出
            } catch (Exception e) {
                attempt++;
                if (attempt == retries) {
                    System.out.println("Failed to update inventory for order ID: " + event.getOrderId() + " after " + retries + " attempts.");
                    throw e; // 达到最大重试次数，抛出异常
                }
                System.out.println("Attempt " + attempt + " failed to update inventory. Retrying...");
                Thread.sleep(RETRY_DELAY_MS); // 等待后重试
            }
        }
    }

    private void logOrder(OrderCreatedEvent event) {
        OrderLog log = new OrderLog();
        log.setOrderId(event.getOrderId());
        log.setAction("ORDER_CREATED");
        log.setTimestamp(LocalDateTime.now());
        orderLogRepository.save(log);
        System.out.println("Logged order creation for order ID: " + event.getOrderId());
    }
}